home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Mac100% 1998 November
/
MAC100-1998-11.ISO.7z
/
MAC100-1998-11.ISO
/
オンラインソフト定点観測
/
ユーティリティ
/
Mops 3.2.sea
/
Mops 3.2
/
Mops ƒ
/
zBase
< prev
next >
Wrap
Text File
|
1998-06-08
|
10KB
|
423 lines
¥ zBase
¥ This file is the PPC equivalent of the 68k "Base" file. It's a
¥ "z" file - it's not target compiled, but is loaded on the PPC itself.
¥ Some PPC defns have already been target compiled in pBase - here we
¥ include all the rest.
¥ [ and ] have been left to here as problems arise if we try to define
¥ them in the target compilation.
¥ ================= MARKER-related words ==================
¥
¥ Before we do anything else, we need to resolve some forward definitions
¥ required by MARKER. MARKER is in pBase since we need it to be already
¥ defined before we load this file, so that it gets a proper file mark.
0 value cdp2use
: (mrk)
cdp2use
dup displace -> CDP 4 +
displace -> DP
CDP (forget)
-echo
;
:f marker_h ( xt -- )
2 + -> cdp2use
['] (mrk) (comp)
;f
:f fmrk ( addr -- )
-> cdp2use (mrk) ;f
¥ ==================================================
false value testing?
false value torture?
: xx db ;
: [ (suspend_compilation) 0 -> state ; immediate
: ] (resume_compilation) -1 -> state ; immediate
¥ Some inline defns:
: 1+ inline{ 1 +} ;
: 2+ inline{ 2 +} ;
: 3+ inline{ 3 +} ;
: 4+ inline{ 4 +} ;
: 1- inline{ 1 -} ;
: 2- inline{ 2 -} ;
: 3- inline{ 3 -} ;
: 4- inline{ 4 -} ;
: 2* inline{ 1 <<} ;
: 2/ inline{ 1 a>>} ;
: 4* inline{ 2 <<} ;
: 4/ inline{ 2 a>>} ;
¥ ANSI words
: CELL+ inline{ 4 +} ;
: CELL- inline{ 4 -} ;
: CELLS inline{ 2 <<} ;
: CHAR+ inline{ 1 +} ;
: CHARS inline{ } ;
4 constant 1CELL ¥ Not ANSI, but useful
¥ (") is in qpCond.
¥ In the 68k version, :a ... ;a is used for action handlers, to set up the
¥ module base register if we're calling a word in a module. On the PPC, our
¥ reloc addr format identifies the segment, so we can take care of everything
¥ in our x-addr and x-array classes. So here we just define :a and ;a to be
¥ the same as : and ;.
: :A postpone : ; immediate
: ;A postpone ; ; immediate
: "
state
IF (") ¥ compiling
ELSE 34 parse ¥ interpreting
THEN
; immediate
: S" postpone " ; immediate ¥ ANSI synonym for "
: ."
state
IF (") postpone type ¥ compiling
ELSE 34 parse type ¥ interpreting
THEN
; immediate
: ABORT"
postpone "
postpone do_abq ; immediate
¥ (* ... *) defines a multi-line comment, which can be very useful. Many
¥ Pascal compilers use these symbols - I thought it better not to use
¥ the C-style /* ... */ since */ already has a meaning.
¥ A useful improvement to the typical Pascal implementation is to keep a
¥ level count so that this kind of comment can be nested.
: (*
1 ¥ initial level count
BEGIN
Mword count 2dup
" (*" s=
IF 2drop 1 + ¥ increment level count
ELSE
" *)" s=
IF 1 - ¥ decrement level count
?dup 0EXIT ¥ and if zero, we're done
THEN
THEN
AGAIN ; immediate
variable NULLOSSTR
0 nullOSstr !
: @WORD ¥ ( -- addr ) Gets next blank-delimited word from input stream,
¥ with no case conversion.
bl word ;
: LIT ¥ ( n -- ) A state-smart version of LITERAL. Corresponds
¥ to LITERAL in Fig-Forth or original Neon, whereas our
¥ present LITERAL is ANSI.
state IF postpone literal THEN ; immediate
: 0, 0 , ; ¥ Compiles an empty cell
: @VAL intrp1 ; ¥ Compiles a number from input stream
: 'TYPE ¥ ( -- 4bytes ) OS type literal
pad 4 bl fill @word count 4 min
pad swap cmove pad @ postpone lit ; immediate
(* RECURSE calls the current definition. We need all the flag bytes
in place, so the regs get set up properly. The second flag byte
is OK already, but we still need to set the first one, with the
#cells in regs on return. So we now decide this if we
haven't already, put the flag byte there, then compile the call.
Note that recursive words must be non-leaf, since the LR has to be
saved. This is looked after by (comp), and in any case the leaf
bit is the top bit in the flag byte we have to store, and we leave
it zero.
*)
: RECURSE
get_rtn_cnts drop
curr-def 2- c!
curr-def 2- (comp)
; immediate
: CHAR @word 1+ c@ ;
: [CHAR] @word 1+ c@ postpone literal ; immediate
: & ¥ ( -- c ) A shorter state-smart version.
@word 1+ c@
postpone lit ; immediate
: $ ¥ State-smart HEX literal word
base >r
hex Mword number postpone lit
r> -> base ; immediate
¥ Str255 stuff already defined, in setup and pBase.
¥ Resource support is in pBase.
¥ ================= Messages and errors ==================
: ?ERROR ¥ ( b -- ) Aborts and prints resource string if true.
¥ Usage: ?error 999
postpone if
intrp1 ( get err# ) postpone literal postpone die
postpone then ; immediate
¥ this is now in pBase:
¥ : (TSTR) ¥ ( id# -- ) Prints string with given resID.
¥ getString type ;
: TYPE# ¥ Prints string for id# in stream
intrp1 postpone lit postpone tStr ; immediate
: .RSTR ¥ ( -- ) print "Msg# ..." then string with given resID
." Msg# " dup . ." : " tStr ;
: MSG# ¥ usage: " Msg# <number>"
intrp1 postpone lit postpone .rStr ; immediate
¥ ====================================
: RDEPTH rp0 rp@ - 4/ 2- ;
: ?RDEPTH rp@ sp0 20 + < ?error 116 ; ¥ err if rtn stk about to
¥ collide with data stk
¥ ========== Type checking ===========
¥ Sometimes we want to check that a non-object parameter to a word is of a
¥ certain type. We give it a unique type code and use TYPCHK.
: TYPCHK <> ?error 179 ;
¥ ====================================
¥ Commonly needed error words. These are forward defined - the main
¥ application should provide a sensible definition, with a nice friendly
¥ alert box, to tell the user in a nice friendly way that things are up
¥ the creek.
forward NOMEM ¥ Call when (not if!) we run out of memory.
forward I/O_ERR ¥ ( err# -- ) Call when there's an I/O error.
: OK? ¥ ( rc -- ) A useful word to use after an I/O op.
?dup 0EXIT I/O_err ;
¥ ======== Various utility words needed later =========
¥ BECOME allows restarting at a given word, with all stacks
¥ empty. This is necessary in menu handlers and other areas
¥ that could create indefinite nesting situations.
' quit vect becomeXT
: BE sp0 sp! rp0 rp! becomeXT quit ;
: (BE) -> becomeXT be ;
: BECOME ¥ Usage: Become newWord - compiles code to Be at runtime
state
IF postpone ['] postpone (be)
ELSE ' -> becomeXT be
THEN ; immediate
: DATETIME
$ 20C @ ;
¥ ============ Tables, lists etc. ===============
(* From Mops 2.5 on, we're trying to be consistent with the way we delimit
various kinds of lists with { ... }. No, we're not trying to copy C,
but let's at least follow the "principle of minimum astonishment".
Thus, with words like xts{, we'll allow a variant "xts {" where you
can put a space before the "{". This is very easy to implement, so
why not?
*)
forward { immediate
: GOBBLE{ ¥ gobbles a "{" which must follow as a separate word.
' ['] { <> ?error 113 ; ¥ "{" expected
: ) 123 die ; immediate ¥ ") read when no list is current"
: (}) 123 die ; immediate ¥ "unmatched }"
' (}) vect } ¥ } will mean different things in different
¥ contexts.
: }OR)? ¥ ( cfa -- cfa b )
dup ['] } = over ['] ) = or ;
: XTS{ ¥ State-smart word to compile or stack a list
¥ of xts. Pulls words from stream, until "}".
0
BEGIN ' }or)?
NWHILE state IF ¥ const_data_ref reloc>const_data postpone @abs
lit_addr
ELSE swap
THEN 1+
REPEAT
drop state IF postpone literal THEN ; immediate
: CFAS{ postpone xts{ ; immediate ¥ Synonyms for compatibility
: CFAS( postpone xts{ ; immediate
: XTS gobble{ postpone xts{ ; immediate
(* SCON defines a string constant. Usage:
scon <name> "a string"
Runtime: ( -- addr len )
Change from Neon: the first nonblank char after the name of the SCON
becomes the delimiter. So " can be used as usual, but anything else can
be used instead, e.g.:
scon <name> /this string contains " as non-delimiter/
*)
: SCON
<BUILDS bl skip-src+
src-start >in @ + c@ ,dlm-str
DOES> count ;
¥ note: INSTEAD is defined in zArgs since it needs locals.
¥ CASE should be used for non-contiguous or dynamically computed values.
¥ This is a modified Eaker/Duncan model.
¥ Our optimization strategy gives quite good code.
: CASE ?comp 302 ; immediate
: OF
postpone over postpone = postpone if
postpone drop ; immediate
: RANGEOF
postpone within? postpone if
postpone drop ; immediate
: ENDOF
postpone else ; immediate
: ENDCASE
postpone drop
BEGIN dup 302 = NWHILE >resolve&equalize REPEAT drop ;
immediate
(* TYPE{ and ENUM{ (synonyms) define a Pascal/C-like enumerated type.
At this stage we don't give a name to the "type" as such, as we can't
do anything really sensible with it. However later we can optionally
load the ENUM-TYPE class which is rather more Pascal-like. But even
without that, the enumeration is very useful by itself.
*)
0 value TYPECNT
' null vect DO_ET ¥ Hook for handling the ENUM-TYPE
¥ class when it's loaded
: ENDLIST? ¥ ( chr -- b )
#lines_read >r
>in @ >r
Mword count 1 = down c@ = and
IF r> drop r> drop true ¥ finished - leave delimiter skipped
ELSE r> >in ! ¥ another list item - reread it
r> #lines_read <>
IF 0 >in ! THEN
false
THEN ;
: ENUM{
0 -> typeCnt ¥ 1st value
BEGIN typeCnt constant 1 ++> typeCnt
& } endlist?
UNTIL
do_ET ;
: TYPE{ enum{ ; ¥ C fans might like this name better
: ENUM gobble{ enum{ ;
¥ note we can't allow "type { ..." since "type" has another
¥ meaning already. But "enum { ..." is OK.
enum{ InMainDic DataInMainDic InOtherMod DataInOtherMod InThisMod }
¥ Relocatable addr types
¥ ========== Error diagnostics ===========
¥ We use special values for nil handles and nil pointers. These are
¥ odd high addresses, so hopefully we'll trap if we try to use them.
: .RTN ¥ ( addr -- )
cr ." From $"
.h 4 spaces
;
: RANGE_ERR ¥ ( index range rtn-addr -- )
dup 1+ 0= ?error 128 ¥ Spurious range error
.rtn
dup -1 <
IF nip ?error 130 ¥ Not an indexed class
ELSE ." Range: " . ." Index: " .
true ?error 129
THEN ;